<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <meta name="description" content="Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像现在我们利用Docker将这个完整项目部署起来，为什么用Docker呢？原因很简单，这种容器技术可以将整个项目用单个容器装起来，仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进" />
  

  
  
  
  
  
  
  <title>win10系统下利用docker部署gunicorn+Flask打造独立镜像 | 南辞的技术博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像现在我们利用Docker将这个完整项目部署起来，为什么用Docker呢？原因很简单，这种容器技术可以将整个项目用单个容器装起来，仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进容器，甚至把这个过程自动化，部署流程就会变得简单、方便。 ​    简单理解就是Docker的镜像就">
<meta property="og:type" content="article">
<meta property="og:title" content="win10系统下利用docker部署gunicorn+Flask打造独立镜像">
<meta property="og:url" content="https://yanlidoushikeke.gitee.io/myhexo/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%88%A9%E7%94%A8docker%E9%83%A8%E7%BD%B2gunicorn-Flask%E6%89%93%E9%80%A0%E7%8B%AC%E7%AB%8B%E9%95%9C%E5%83%8F/index.html">
<meta property="og:site_name" content="南辞的技术博客">
<meta property="og:description" content="Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像现在我们利用Docker将这个完整项目部署起来，为什么用Docker呢？原因很简单，这种容器技术可以将整个项目用单个容器装起来，仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进容器，甚至把这个过程自动化，部署流程就会变得简单、方便。 ​    简单理解就是Docker的镜像就">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716100711_31478.png">
<meta property="og:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716110704_84934.png">
<meta property="og:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716110709_50860.png">
<meta property="og:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716110725_66656.png">
<meta property="og:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716110756_47834.png">
<meta property="og:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716110737_84282.png">
<meta property="article:published_time" content="2021-04-23T07:31:10.000Z">
<meta property="article:modified_time" content="2021-04-23T07:32:06.671Z">
<meta property="article:author" content="南辞">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://v3u.cn/v3u/Public/js/editor/attached/20200716100711_31478.png">
  
  
    <link rel="icon" href="/tefuir/css/images/favicon.ico">
  
  
<link rel="stylesheet" href="/tefuir/css/style.css">

  

  
  <!-- baidu webmaster push -->
  <script src='//push.zhanzhang.baidu.com/push.js'></script>
<meta name="generator" content="Hexo 5.2.0"><link rel="alternate" href="/tefuir/atom.xml" title="南辞的技术博客" type="application/atom+xml">
</head>
<body class="home blog custom-background custom-font-enabled single-author">
  <div id="page" class="hfeed site">
      <header id="masthead" class="site-header" role="banner">
    <hgroup>
      <h1 class="site-title">
        <a href="/tefuir/" title="南辞的技术博客" rel="home">南辞的技术博客</a>
      </h1>
      
        <h2 class="site-description hitokoto"></h2>
        <script type="text/javascript" src="https://v1.hitokoto.cn/?encode=js"></script>
      
    </hgroup>

    <nav id="site-navigation" class="main-navigation" role="navigation">
            <button class="menu-toggle">菜单</button>
            <a class="assistive-text" href="/#content" title="跳至内容">跳至内容</a><!--TODO-->
            <div class="menu-main-container">
                <ul id="menu-main" class="nav-menu">
                
                    <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/tefuir/">Home</a></li>
                
                    <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="/tefuir/archives">Archives</a></li>
                
                </ul>
            </div>
    </nav>
</header>

      <div id="main" class="wrapper">
        <div id="primary" class="site-content"><div id="content" role="main"><article id="post-win10系统下利用docker部署gunicorn-Flask打造独立镜像" class="post-win10系统下利用docker部署gunicorn-Flask打造独立镜像 post type-post status-publish format-standard hentry">
    <!---->

      <header class="entry-header">
        
        
  
    <h1 class="entry-title article-title">
      win10系统下利用docker部署gunicorn+Flask打造独立镜像
    </h1>
  

        
        <div class="comments-link">
            
            <a href="javascript:void(0);" data-url="https://yanlidoushikeke.gitee.io/myhexo/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%88%A9%E7%94%A8docker%E9%83%A8%E7%BD%B2gunicorn-Flask%E6%89%93%E9%80%A0%E7%8B%AC%E7%AB%8B%E9%95%9C%E5%83%8F/" data-id="cknzsqft5000154u0fojuc4c7" class="leave-reply bdsharebuttonbox" data-cmd="more">Share</a>
        </div><!-- .comments-link -->
      </header><!-- .entry-header -->

    <div class="entry-content">
      
        <h1 id="Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn-Flask打造独立镜像"><a href="#Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn-Flask打造独立镜像" class="headerlink" title="Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像"></a>Docker在手，天下我有，在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像</h1><p>现在我们利用Docker将这个完整项目部署起来，为什么用Docker呢？原因很简单，这种容器技术可以将整个项目用单个容器装起来，仅仅只需要维护一个简单的配置文件就告诉电脑每次部署要把什么东西装进容器，甚至把这个过程自动化，部署流程就会变得简单、方便。</p>
<p>​    简单理解就是Docker的镜像就类似《精灵宝可梦》中小智手里的精灵球，我们的项目就类似那些宠物小精灵，当我们开发完毕就可以利用DockerFile对项目进行打包制作成镜像(小精灵被吸入精灵球)，部署时就可以理解为小精灵被释放出来进行战斗(通过打包好的镜像运行容器)，而Docker的仓库则提高了镜像的便捷性，可以让我们随时随地只要联网就可以使用自己的镜像(相当于小智不用随身携带精灵球，而是通过网络随时下载需要的精灵球)。</p>
<p>​    同时Docker其强大的跨平台特性，可以让我们在任何系统下部署项目，包括经常令人诟病的Windows，值得一提的是本次在Win10下部署项目的流程同样适用于Centos、Mac os、Ubuntu等系统，其兼容性可见一斑。</p>
<p>​    关于Win10如何折腾和配置Docker，请参照这篇文章:<a target="_blank" rel="noopener" href="https://v3u.cn/a_id_149">win10系统下把玩折腾DockerToolBox以及更换国内镜像源(各种神坑)</a></p>
<p>​    首先简单看一下项目结构:</p>
<p><img src="https://v3u.cn/v3u/Public/js/editor/attached/20200716100711_31478.png" alt="img"></p>
<p>​    manage.py是项目的入口文件，这里我们利用Sockert.io让Flask支持Websocket</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br></pre></td><td class="code"><pre><span class="line">from flask import Flask</span><br><span class="line">from flask_sqlalchemy import SQLAlchemy</span><br><span class="line">import pymysql</span><br><span class="line">from flask import request,jsonify</span><br><span class="line">from flask_cors import CORS</span><br><span class="line">from flask_socketio import SocketIO,send,emit,join_room, leave_room</span><br><span class="line">import urllib.parse</span><br><span class="line">import user_view</span><br><span class="line"></span><br><span class="line">from celery import Celery</span><br><span class="line">from datetime import timedelta</span><br><span class="line"></span><br><span class="line">pymysql.install_as_MySQLdb()</span><br><span class="line"> </span><br><span class="line">app &#x3D; Flask(__name__)</span><br><span class="line">app.config[&quot;SQLALCHEMY_DATABASE_URI&quot;] &#x3D; &quot;mysql:&#x2F;&#x2F;root:root@localhost:3306&#x2F;md&quot;</span><br><span class="line">app.config[&#39;SQLALCHEMY_COMMIT_ON_TEARDOWN&#39;] &#x3D; True</span><br><span class="line">app.config[&#39;SQLALCHEMY_TRACK_MODIFICATIONS&#39;] &#x3D; True</span><br><span class="line"></span><br><span class="line">app.config[&#39;BROKER_URL&#39;] &#x3D; &#39;redis:&#x2F;&#x2F;localhost:6379&#39;</span><br><span class="line">app.config[&#39;CELERY_RESULT_BACKEND&#39;] &#x3D; &#39;redis:&#x2F;&#x2F;localhost:6379&#39;</span><br><span class="line">app.config[&#39;CELERY_ACCEPT_CONTENT&#39;] &#x3D; [&#39;json&#39;, &#39;pickle&#39;]</span><br><span class="line">app.config[&#39;REDIS_URL&#39;] &#x3D; &#39;redis:&#x2F;&#x2F;localhost:6379&#39;</span><br><span class="line">app.config[&#39;JSON_AS_ASCII&#39;] &#x3D; False</span><br><span class="line"></span><br><span class="line">CORS(app,cors_allowed_origins&#x3D;&quot;*&quot;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">app.register_blueprint(user_view.user)</span><br><span class="line"></span><br><span class="line">db &#x3D; SQLAlchemy(app)</span><br><span class="line"></span><br><span class="line">socketio &#x3D; SocketIO(app,cors_allowed_origins&#x3D;&#39;*&#39;,async_mode&#x3D;&quot;threading&quot;,message_queue&#x3D;app.config[&#39;CELERY_RESULT_BACKEND&#39;])</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">celery &#x3D; Celery(app.name)</span><br><span class="line">celery.conf.update(app.config)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">celery.conf.CELERYBEAT_SCHEDULE &#x3D; &#123;</span><br><span class="line">        </span><br><span class="line">        &quot;test&quot;:&#123;</span><br><span class="line">            &quot;task&quot;:&quot;get_cron&quot;,</span><br><span class="line">            &quot;schedule&quot;:timedelta(seconds&#x3D;10)</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">@celery.task(name&#x3D;&quot;get_cron&quot;)</span><br><span class="line">def get_cron():</span><br><span class="line">    </span><br><span class="line">    get_sendback.delay()</span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">@celery.task()</span><br><span class="line">def get_sendback():</span><br><span class="line">    </span><br><span class="line">    socketio.emit(&#39;sendback&#39;,&#39;message&#39;,broadcast&#x3D;True)</span><br><span class="line"></span><br><span class="line">@app.route(&#39;&#x2F;task&#39;)</span><br><span class="line">def start_background_task():</span><br><span class="line">    get_sendback.delay()</span><br><span class="line">    return &#39;开始&#39;</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line">@app.route(&#39;&#x2F;&#39;,methods&#x3D;[&#39;GET&#39;,&#39;POST&#39;,&quot;PUT&quot;,&quot;DELETE&quot;])</span><br><span class="line">def hello_world():</span><br><span class="line">    #res &#x3D; db.session.execute(&quot;insert into user (&#96;username&#96;) values (&#39;123&#39;) &quot;)</span><br><span class="line"></span><br><span class="line">    # res &#x3D; db.session.execute(&quot; select id,username from user &quot;).fetchall()</span><br><span class="line"></span><br><span class="line">    # data &#x3D; request.args.get(&quot;id&quot;)</span><br><span class="line"></span><br><span class="line">    # #data &#x3D; request.form.get(&quot;id&quot;)</span><br><span class="line"></span><br><span class="line">    # print(data)</span><br><span class="line"></span><br><span class="line">    # print(res)</span><br><span class="line"></span><br><span class="line">    # #return &#39;Hello Flask&#39;</span><br><span class="line">    # return jsonify(&#123;&#39;result&#39;: [dict(row) for row in res]&#125;)</span><br><span class="line"></span><br><span class="line">    return jsonify(&#123;&#39;message&#39;:&#39;你好,Docker&#39;&#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">@socketio.on(&#39;join&#39;)</span><br><span class="line">def on_join(data):</span><br><span class="line">    username &#x3D; &#39;user1&#39;</span><br><span class="line">    room &#x3D; &#39;room1&#39;</span><br><span class="line">    join_room(room)</span><br><span class="line">    send(username + &#39; has entered the room.&#39;, room&#x3D;room)</span><br><span class="line"></span><br><span class="line">@socketio.on(&#39;message&#39;)</span><br><span class="line">def handle_message(message):</span><br><span class="line">    message &#x3D; urllib.parse.unquote(message)</span><br><span class="line">    print(message)</span><br><span class="line">    send(message,broadcast&#x3D;True)</span><br><span class="line"></span><br><span class="line">@socketio.on(&#39;connect&#39;, namespace&#x3D;&#39;&#x2F;chat&#39;)</span><br><span class="line">def test_connect():</span><br><span class="line">    emit(&#39;my response&#39;, &#123;&#39;data&#39;: &#39;Connected&#39;&#125;)</span><br><span class="line"></span><br><span class="line">@socketio.on(&#39;disconnect&#39;, namespace&#x3D;&#39;&#x2F;chat&#39;)</span><br><span class="line">def test_disconnect():</span><br><span class="line">    print(&#39;Client disconnected&#39;)</span><br><span class="line"> </span><br><span class="line">@app.route(&quot;&#x2F;sendback&quot;,methods&#x3D;[&#39;GET&#39;])</span><br><span class="line">def sendback():</span><br><span class="line"></span><br><span class="line">    socketio.emit(&#39;sendback&#39;,&#39;message&#39;)</span><br><span class="line"></span><br><span class="line">    return &#39;ok&#39;</span><br><span class="line"> </span><br><span class="line">if __name__ &#x3D;&#x3D; &#39;__main__&#39;:</span><br><span class="line"></span><br><span class="line">    socketio.run(app,debug&#x3D;True,host&#x3D;&quot;0.0.0.0&quot;,port&#x3D;5000)</span><br></pre></td></tr></table></figure>

<p>​    接下来使用Gunicorn+gevent来运行Flask项目，Gunicorn服务器作为wsgi app的容器，能够与各种Web框架兼容（flask，django等）,得益于gevent等技术，使用Gunicorn能够在基本不改变wsgi app代码的前提下，大幅度提高wsgi app的性能。那到底怎么提升性能？说简单点，Gunicorn 默认的网络模型是 select ，当我们把worker 替换成 gevent 后，则改为 epoll 监听模型，关于select、poll、epoll请参照这篇文章:<a target="_blank" rel="noopener" href="https://v3u.cn/a_id_107">关于Tornado:真实的异步和虚假的异步</a>，这里不再赘述。</p>
<p>​    安装相应的库</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install gunicorn gevent --user</span><br></pre></td></tr></table></figure>

<p>​    编辑项目目录下的gunicorn.conf.py</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">workers &#x3D; 3    # 进程数</span><br><span class="line">worker_class &#x3D; &quot;gevent&quot;   # 异步模式</span><br><span class="line">bind &#x3D; &quot;0.0.0.0:5000&quot;</span><br></pre></td></tr></table></figure>

<p>​    由于Gunicorn并不支持Windows环境，所以只需要写好配置，不需要运行。</p>
<p>​    编辑项目目录下的requirements.txt文件，这里面都是我们项目所依赖的库</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">flask&#x3D;&#x3D;1.0.2</span><br><span class="line">flask-cors</span><br><span class="line">flask-socketio</span><br><span class="line">flask-sqlalchemy</span><br><span class="line">pymysql</span><br><span class="line">celery</span><br><span class="line">gunicorn</span><br><span class="line">gevent</span><br><span class="line">redis&#x3D;&#x3D;3.3.11</span><br></pre></td></tr></table></figure>

<p>​    随后在项目目录下创建一个 Dockerfile 文件，这个文件可以理解为打包镜像的脚本，你需要这个镜像做什么，就把任务写到脚本中，Docker通过执行这个脚本来打包镜像</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">FROM python:3.6</span><br><span class="line">WORKDIR &#x2F;Project&#x2F;myflask</span><br><span class="line"></span><br><span class="line">COPY requirements.txt .&#x2F;</span><br><span class="line">RUN pip install -r requirements.txt -i https:&#x2F;&#x2F;pypi.tuna.tsinghua.edu.cn&#x2F;simple</span><br><span class="line"></span><br><span class="line">COPY . .</span><br><span class="line">ENV LANG C.UTF-8</span><br><span class="line">CMD [&quot;gunicorn&quot;, &quot;manage:app&quot;, &quot;-c&quot;, &quot;.&#x2F;gunicorn.conf.py&quot;]</span><br></pre></td></tr></table></figure>

<p>​    可以看到，我们项目的镜像首先基于python3.6这个基础镜像，然后声明项目目录在/Project/myflask中，拷贝依赖表，之后安装相应的依赖，这里在安装过程中我们指定了国内的源用来提高打包速度，最后利用gunicorn运行项目，值得一提的是，ENV LANG C.UTF-8是为了声明Docker内部环境中的编码，防止中文乱码问题。</p>
<p>​    最后我们就可以愉快的打包整个项目了，在项目根目录下执行</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker build -t &#39;myflask&#39; .</span><br></pre></td></tr></table></figure>

<p> <img src="https://v3u.cn/v3u/Public/js/editor/attached/20200716110704_84934.png" alt="img"></p>
<p>​    此时看到Docker通过读取Dockerfile文件来下载所需的基础镜像和依赖库，这里一定要指定Docker的下载源，否则速度会非常缓慢，打包好的镜像文件大概有1g左右。</p>
<p>​    下载结束之后，可以看到myflask这个镜像已经静静躺在镜像库中了，运行</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker images</span><br></pre></td></tr></table></figure>

<p>​    命令来查看</p>
<p><img src="https://v3u.cn/v3u/Public/js/editor/attached/20200716110709_50860.png" alt="img"></p>
<p>​    然后我们就可以利用这个镜像来通过容器跑Flask项目了，运行命令</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --rm -p 5000:5000 myflask</span><br></pre></td></tr></table></figure>

<p>​    这里的命令是通过端口映射把docker内部的端口5000映射到宿主机的5000端口上，后面的参数是镜像名称。我们看到，在Win10下，已经不可思议的通过Gunicorn把Flask跑起来了，这在之前没有Docker技术之前是不可想象的。</p>
<p><img src="https://v3u.cn/v3u/Public/js/editor/attached/20200716110725_66656.png" alt="img"></p>
<p>​    通过网址访问一下，这里注意一点，就是Windows系统下，访问Docker容器需要通过分配的ip来访问，而不是我们常用的localhost。</p>
<p><img src="https://v3u.cn/v3u/Public/js/editor/attached/20200716110756_47834.png" alt="img"></p>
<p>​    完全没有任何问题。</p>
<p><img src="https://v3u.cn/v3u/Public/js/editor/attached/20200716110737_84282.png" alt="img"></p>
<p>​    结语：到这里我们的 Docker+Flask + Gunicorn就部署完毕了，将这个镜像上传Dockerhub仓库，在任何时间、任何地点、任何系统上，只要连着网、只要我们想，就都可以在短短1分钟之内部署好我们的项目，这就是Docker技术对开发人员最好的馈赠。最后奉上项目地址:<a target="_blank" rel="noopener" href="https://gitee.com/QiHanXiBei/myflask">https://gitee.com/QiHanXiBei/myflask</a></p>

      
    </div><!-- .entry-content -->

    <footer class="entry-meta">
    <a href="/tefuir/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%88%A9%E7%94%A8docker%E9%83%A8%E7%BD%B2gunicorn-Flask%E6%89%93%E9%80%A0%E7%8B%AC%E7%AB%8B%E9%95%9C%E5%83%8F/">
    <time datetime="2021-04-23T07:31:10.000Z" class="entry-date">
        2021-04-23
    </time>
</a>
    
    
    </footer>
</article>


    
<nav class="nav-single">
    <h3 class="assistive-text">文章导航</h3>
    
        <span class="nav-previous"><a href="/tefuir/2021/04/23/python3-Flask%E7%BB%93%E5%90%88Socket-io%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E5%9C%A8%E7%BA%BF%E5%AE%A2%E6%9C%8D%E7%B3%BB%E7%BB%9F/" rel="prev"><span class="meta-nav">←</span> python3+Flask结合Socket.io简单实现在线客服系统</a></span>
    
    
        <span class="nav-next"><a href="/tefuir/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%9F%BA%E4%BA%8Edocker%E9%85%8D%E7%BD%AEelasticsearch%E9%85%8D%E5%90%88python3%E8%BF%9B%E8%A1%8C%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/" rel="next">win10系统下基于docker配置elasticsearch配合python3进行全文检索 <span class="meta-nav">→</span></a></span>
    
</nav><!-- .nav-single -->







</div></div>
        <div id="secondary" class="widget-area" role="complementary">
  
    <aside id="search" class="widget widget_search"><form role="search" method="get" accept-charset="utf-8" id="searchform" class="searchform" action="//google.com/search">
    <div>
        <input type="text" value="" name="s" id="s" />
        <input type="submit" id="searchsubmit" value="搜索" />
    </div>
</form></aside>
  
    
  
    
  
    
  <aside class="widget">
    <h3 class="widget-title">Recents</h3>
    <div class="widget-content">
      <ul>
        
          <li>
            <a href="/tefuir/2021/04/26/python%E5%9F%BA%E7%A1%80%E7%90%86%E8%AE%BA%E5%AE%9D%E5%85%B8/">python基础理论宝典</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/python3-Flask%E7%BB%93%E5%90%88Socket-io%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E5%9C%A8%E7%BA%BF%E5%AE%A2%E6%9C%8D%E7%B3%BB%E7%BB%9F/">python3+Flask结合Socket.io简单实现在线客服系统</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%88%A9%E7%94%A8docker%E9%83%A8%E7%BD%B2gunicorn-Flask%E6%89%93%E9%80%A0%E7%8B%AC%E7%AB%8B%E9%95%9C%E5%83%8F/">win10系统下利用docker部署gunicorn+Flask打造独立镜像</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/win10%E7%B3%BB%E7%BB%9F%E4%B8%8B%E5%9F%BA%E4%BA%8Edocker%E9%85%8D%E7%BD%AEelasticsearch%E9%85%8D%E5%90%88python3%E8%BF%9B%E8%A1%8C%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/">win10系统下基于docker配置elasticsearch配合python3进行全文检索</a>
          </li>
        
          <li>
            <a href="/tefuir/2021/04/23/%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%97%AE%E9%A2%98/">服务器问题</a>
          </li>
        
      </ul>
    </div>
  </aside>

  
    
  
    
  
</div>
      </div>
      <footer id="colophon" role="contentinfo">
    <p>&copy; 2021 南辞
    All rights reserved.</p>
    <p>Powered by <a href="http://hexo.io/" target="_blank">Hexo</a></p>
</footer>
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"1","bdMiniList":false,"bdPic":"","bdStyle":"2","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='/js/share.js'];</script>

<script src="/js/jquery-3.3.1.min.js"></script>


  
<link rel="stylesheet" href="/tefuir/fancybox/jquery.fancybox.css">

  
<script src="/tefuir/fancybox/jquery.fancybox.pack.js"></script>




<script src="/tefuir/js/script.js"></script>


<script src="/js/navigation.js"></script>

<div id="bg"></div>

  </div>
</body>
</html>